package oop.ex2.objects;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;

import oop.ex2.compiler.VariablesException;
import oop.ex2.enums.MethodEnum;
import oop.ex2.enums.VariableValueEnum;

public class Variable {
    private String name;
    private String type;
    private String value;
    private HashMap<String, Method> methods;
    private ArrayList<Variable> variables;

    public Variable(String name, String type, String value, HashMap<String, Method> methods,
            ArrayList<Variable> variables) throws VariablesException {
        this.name = name;
        this.type = type;
        this.value = value;
        this.methods = methods;
        this.variables = variables;
        checkValid();
    }

    private void checkValid() throws VariablesException {
        for(Variable variable : variables) {
            if(variable.getName().equals(name)) {
                throw new VariablesException("Variable with name '" + name + "' already exists.");
            }
        }
        
        value = value.replaceAll("=", "");
        value = value.trim();
        boolean isValid = false;
        Matcher valueMatcher = VariableValueEnum.valueOf(type.toUpperCase()).getEnumPattern().matcher(value);
        Matcher parenthesisMatcher = MethodEnum.PARENTHESIS.getEnumPattern().matcher(value);
        if (!valueMatcher.matches()) {
            if (parenthesisMatcher.find()) { // Value is a method.
                value = value.replaceAll("\\(", "");
                value = value.replaceAll("\\)", "");
                for (String method : methods.keySet()) {
                    if (value.equals(methods.get(method).getName())) {
                        if (type.equals(methods.get(method).getReturnType())) {
                            isValid = true;
                        }
                    }
                }
            } else { // Value is a variable.
                for (Variable variable : variables) {
                    if (value.equals(variable.getName())) {
                        if (type.equals(variable.getType())) {
                            isValid = true;
                        }
                    }
                }
            }
        } else {
            isValid = true;
        }
        if (!isValid) {
            throw new VariablesException("Value '" + value + "' mismatch for type '" + type + "'");
        }
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}
